﻿import {store} from "@/components/chart/common/store";
import {FloatMenu} from "@/components/contro/floatmenu";

const chart = function (myChart, opt) {
  let _mData = opt.series[0].data;

  delete opt.others.data;
  delete opt.others.datamarking;

  const self = this;
  let chart_opt = {
    tooltip: {
      formatter: function (args) {
        return opt.others.dimensionField.name + ":" + args.name + "<br/>" + opt.others.measureField.name + ":" + Number(args.value).toMeasureFormart(opt.others.measureField.numberFormat) + "<br/>占比:" + args.percent + "%";
      }
    }
  };

  const labelFormatter = function (args) {
    let name = args.name;
    return opt.others.labelFormater.replace(/\<|\%|\=|\>/g, "").replace("name", name).replace("value", args.value.toMeasureFormart(chart_opt.others.measureField.numberFormat)).replace("ratio", args.percent + "%");
  };

  const setOption = (opt, ext) => {
    if (ext) {
      chart_opt = $.extend(true, chart_opt, opt);
    } else {
      chart_opt = opt;
    }
    chart_opt.series[0].label.formatter = labelFormatter;
    myChart.setOption(chart_opt);
  };

  //响应点击事件
  myChart.on("click", 'series', args => {
    const callData = [{
      field: chart_opt.others.dimensionField,
      value: [args.name]
    }];
    if (self.onselected) {
      self.onselected(callData);
    }
  });

  //轮播的定时器
  let timer;
  //轮播开关
  let state = true;
  //轮播方法
  const carousel = () => {
    let index = 0;
    if (timer) {
      clearInterval(timer)
    }
    if (opt.others.carousel && opt.others.carousel.enable) {
      timer = setInterval(() => {
        if (!state) {
          return false
        }
        index = index + 1 >= chart_opt.series[0].data.length ? 0 : index + 1
        myChart.dispatchAction({
          type: 'downplay',
          seriesIndex: 0,
        })
        myChart.dispatchAction({
          type: 'highlight',
          seriesIndex: 0,
          dataIndex: index
        })
        myChart.dispatchAction({
          type: 'showTip',
          seriesIndex: 0,
          dataIndex: index
        });
      }, opt.others.carousel.speed)
    }
  }
  //鼠标移入，关闭轮播
  myChart.on('mouseover', () => {
    state = false
  })

  //鼠标移出时，开启轮播
  myChart.on('globalout', () => {
    state = true
  })

  //响应右击事件
  myChart.on("contextmenu", 'series', args => {
    myChart.getDom().oncontextmenu = () => {
      return false
    };
    const callData = [{
      field: chart_opt.others.dimensionField,
      value: [args.name]
    }];
    if (callData && callData.length) {
      let menus = []
      menus.push({
        label: "删除选中项",
        onclick: () => {
          _.remove(chart_opt.series[0].data, item => item.name == callData[0].value[0]);
          setOption(chart_opt);
          //清除选框
          myChart.dispatchAction({
            type: "brush",
            areas: []
          });
          //触发删除事件
          if (self.onRemoveItem) {
            self.onRemoveItem(callData);
          }
        }
      });
      menus.push({
        label: "升序",
        onclick: () => {
          chart_opt.series[0].data = _.orderBy(chart_opt.series[0].data, 'value');
          setOption(chart_opt);
        }
      }, {
        label: "降序",
        onclick: function () {
          chart_opt.series[0].data = _.orderBy(chart_opt.series[0].data, 'value', 'desc');
          setOption(chart_opt);
        }
      }, {
        label: "保存为图片",
        onclick: function () {
          const url = myChart.getDataURL({
            type: 'png'
          });
          const a = document.createElement("a");
          a.href = url;
          a.download = name;
          a.click();
          document.body.removeChild(a);
        }
      });
      FloatMenu.show("echart-menus", menus);
    }
  });

  if (opt) {
    setOption(opt, true);
    chart_opt.series.forEach(function (d) {
      d.label.formatter = labelFormatter;
    });
  }

  this.setOption = setOption;

  this.update = (data) => {
    _mData = data;
    chart_opt.series[0].data = data.map(function (d) {
      return {
        value: d[chart_opt.others.measureField.name],
        name: d[chart_opt.others.dimensionField.name]
      };
    });
    //提取一级维度
    const categories = data.map(d => d[chart_opt.others.dimensionField.name]);
    chart_opt.legend.data = categories;
    chart_opt.others.categories = categories;
    setOption(chart_opt, true);
  }

  this.removeChart = () => {
    if (timer) {
      clearInterval(timer)
    }
    if (!myChart.isDisposed()) {
      myChart.off('contextmenu');
      myChart.off('click');
      myChart.dispose()
    }
  };

  carousel();
};
//饼图
export const buildChart = (myChart, data, columnFields, rowFields, options) => {
  const fields = columnFields.concat(rowFields);
  //维度
  let dimensionField = fields.find(d => {
    return d.slaveType === 0;
  });
  //度量
  let measureField = fields.find(d => {
    return d.slaveType === 1;
  });

  if (!dimensionField || !measureField) {
    return false;
  }

  const config = options.chartConfig;

  if (dimensionField.dataType == 4) {
    data = data.sort((a, b) => a[dimensionField.name] - b[dimensionField.name])
  }
  //提取一级维度
  const categories = data.map(d => d[dimensionField.name])

  //数据条标签配置
  let labelOption = {
    show: config.textStyle["display"] !== "none",
    fontSize: config.textStyle["font-size"],
    fontFamily: config.textStyle["font-family"],
    color: config.textStyle["fill"],
    rotate: config.labelRotate
  }
  //通用文字样式
  let textStyle = {
    color: labelOption.color,
    fontSize: labelOption.fontSize,
    fontFamily: labelOption.fontFamily
  }

  const series = {
    type: "pie",
    data: [],
    label: labelOption,
    labelLine: {
      show: labelOption.show,
      lineStyle: {
        color: labelOption.color
      },
      smooth: true
    },
    avoidLabelOverlap: true,
    roseType: config.roseType,
    radius: [config.scale * 100 + "%", (config.outerScale || 0.9) * 100 + "%"],
    itemStyle: {
      borderRadius: 10,
      borderColor: '#fff',
      borderWidth: 2
    },
  };
  series.data = data.map(d => {
    return {
      value: d[measureField.name],
      name: d[dimensionField.name]
    };
  });

  const option = {
    tooltip: {
      trigger: 'item'
    },
    aria: {
      enable: store.enableDecal,
      decal: {
        show: store.enableDecal
      }
    },
    toolbox: {
      show: true,
      orient: 'vertical',
      left: 'right',
      top: 'center',
      feature: {
        mark: {show: true},
        saveAsImage: {show: true},
        dataView: {show: store.isEdit, readOnly: false}
      }
    },
    legend: {
      left: 'center',
      show: config.showLegend == undefined ? true : config.showLegend,
      type: 'scroll',
      textStyle: textStyle
    },
    series: [],
    others: {
      dimensionField: dimensionField,
      measureField: measureField,
      categories: categories,
      data: data,
      labelFormater: config.labelFormater || "<%=name%>: <%=ratio%>",
      datamarking: options.dataMarking
    }
  };

  config.legendPosition = config.legendPosition || "top";
  if (config.legendPosition == "left") {
    option.legend.orient = "vertical";
    option.legend.x = "left";
  } else if (config.legendPosition == "leftBottom") {
    option.legend.orient = "vertical";
    option.legend.x = "left";
    option.legend.y = "bottom";
  } else if (config.legendPosition == "right") {
    option.legend.orient = "vertical";
    option.legend.x = "right";
    option.toolbox.left = 20;
  } else if (config.legendPosition == "rightBottom") {
    option.legend.orient = "vertical";
    option.legend.x = "right";
    option.legend.y = "bottom";
    option.toolbox.left = 20;
  } else if (config.legendPosition == "bottom") {
    option.legend.y = "bottom";
  }

  option.series.push(series);
  option.others.carousel = config.carousel;
  const chartInstance = new chart(myChart, option);
  return chartInstance;
};



